package main;

/*
 * Lesson02.java
 *
 * Created on July 10, 2003, 2:33 PM
 */
import java.util.Date;
import javax.media.opengl.GL;
import javax.media.opengl.GLAutoDrawable;
import javax.media.opengl.GLEventListener;
import javax.media.opengl.glu.GLU;

/** Port of the NeHe OpenGL Tutorial (Lesson 2)
 * to Java using the Jogl interface to OpenGL.  Jogl can be obtained
 * at http://jogl.dev.java.net/
 *
 * @author Kevin Duling (jattier@hotmail.com)
 */
class Renderer implements GLEventListener
{

    private GLU glu = new GLU();
    
    private CS455 cs455;
    
    private Date lastTime = new Date();
    
    private boolean firstFrame = true;
    
    /** Called by the drawable to initiate OpenGL rendering by the client.
     * After all GLEventListeners have been notified of a display event, the
     * drawable will swap its buffers if necessary.
     * @param gLDrawable The GLAutoDrawable object.
     */
    
    public Renderer(CS455 cs455)
    {
        super();
        setCs455(cs455);
    }
    public void display(GLAutoDrawable gLDrawable)
    {
        
        final GL gl = gLDrawable.getGL();
        gl.glClear(GL.GL_COLOR_BUFFER_BIT | GL.GL_DEPTH_BUFFER_BIT);
        gl.glDisable(GL.GL_DEPTH_TEST);
        
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        
        gl.glOrtho(0,800,0,800,-1.0,1.0);
        
        if(firstFrame)
        {
            getCs455().transform();
            //cs455.viewPort();
            //firstFrame = false;
        }
        
        //cs455.perspective();
        
        
        getCs455().drawPolygons(gl);
        
        
     
        gl.glFlush();
        
        Date now = new Date();
        //System.out.println("Last Frame: "+(now.getTime() - lastTime.getTime()));
        lastTime = now;
        //while(true){}
    }

    /** Called when the display mode has been changed.  <B>!! CURRENTLY UNIMPLEMENTED IN JOGL !!</B>
     * @param gLDrawable The GLAutoDrawable object.
     * @param modeChanged Indicates if the video mode has changed.
     * @param deviceChanged Indicates if the video device has changed.
     */
    public void displayChanged(GLAutoDrawable gLDrawable, boolean modeChanged, boolean deviceChanged)
    {
    }

    /** Called by the drawable immediately after the OpenGL context is
     * initialized for the first time. Can be used to perform one-time OpenGL
     * initialization such as setup of lights and display lists.
     * @param gLDrawable The GLAutoDrawable object.
     */
    public void init(GLAutoDrawable gLDrawable)
    {
        GL gl = gLDrawable.getGL();
        gl.glClearColor(0.5f, 0.5f, 0.5f, 0.0f);
        
        gl.glClearDepth(1.0);
        
        //gl.glEnable(GL.GL_DEPTH_TEST);
        //gl.glDepthFunc(GL.GL_LEQUAL);
        //gl.glHint(GL.GL_PERSPECTIVE_CORRECTION_HINT, gl.GL_NICEST);
        
        //gl.glShadeModel(GL.GL_BLEND);
        
        //setCs455(new CS455());
        
        //getCs455().loadData("quads.dat");
        getCs455().buildWorld();
    }

    /** Called by the drawable during the first repaint after the component has
     * been resized. The client can update the viewport and view volume of the
     * window appropriately, for example by a call to
     * GL.glViewport(int, int, int, int); note that for convenience the component
     * has already called GL.glViewport(int, int, int, int)(x, y, width, height)
     * when this method is called, so the client may not have to do anything in
     * this method.
     * @param gLDrawable The GLAutoDrawable object.
     * @param x The X Coordinate of the viewport rectangle.
     * @param y The Y coordinate of the viewport rectanble.
     * @param width The new width of the window.
     * @param height The new height of the window.
     */
    public void reshape(GLAutoDrawable gLDrawable, int x, int y, int width, int height)
    {
        final GL gl = gLDrawable.getGL();

        if (height <= 0) // avoid a divide by zero error!
        {
            height = 1;
        }
        final float h = (float) width / (float) height;
        gl.glViewport(0, 0, width, height);
        gl.glMatrixMode(GL.GL_PROJECTION);
        gl.glLoadIdentity();
        glu.gluPerspective(45.0f, h, 1.0, 20.0);
        gl.glMatrixMode(GL.GL_MODELVIEW);
        gl.glLoadIdentity();
    }

    public CS455 getCs455()
    {
        return cs455;
    }

    public void setCs455(CS455 cs455)
    {
        this.cs455 = cs455;
    }
}
